import configUrl from '@/util/url.js';
import {
	pathToBase64,
	base64ToPath
} from '@/util/mmmm-image-tools/index.js';

import permision from "@/js_sdk/wa-permission/permission";

/* #ifdef APP-PLUS */
/* #endif */

let rad = (d) => {
	return d * Math.PI / 180.0;
}

let getDistance = (lat1, lng1, lat2, lng2) => {
	let radLat1 = rad(lat1);
	let radLat2 = rad(lat2);
	let a = radLat1 - radLat2;
	let b = rad(lng1) - rad(lng2);
	let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));

	s = s * 6378.137; // EARTH_RADIUS;
	s = Math.round(s * 10000) / 10000; //输出为公里

	let distance = s;
	let distance_str = "";

	if (parseInt(distance) >= 1) {
		distance_str = distance.toFixed(1) + "km";
	} else {
		distance_str = distance * 1000 + "m";
	}

	return s;
}

let deepClone = (target) => {
	// 定义一个变量
	let result;
	// 如果当前需要深拷贝的是一个对象的话
	if (typeof target === 'object') {
		// 如果是一个数组的话
		if (Array.isArray(target)) {
			result = []; // 将result赋值为一个数组，并且执行遍历
			for (let i in target) {
				// 递归克隆数组中的每一项
				result.push(deepClone(target[i]))
			}
			// 判断如果当前的值是null的话；直接赋值为null
		} else if (target === null) {
			result = null;
			// 判断如果当前的值是一个RegExp对象的话，直接赋值
		} else if (target.constructor === RegExp) {
			result = target;
		} else {
			// 否则是普通对象，直接for in循环，递归赋值对象的所有值
			result = {};
			for (let i in target) {
				result[i] = deepClone(target[i]);
			}
		}
		// 如果不是对象的话，就是基本数据类型，那么直接赋值
	} else {
		result = target;
	}
	// 返回最终结果
	return result;
}

let cleanData = (target) => {
	let ret = {};

	Object.keys(target).forEach((key) => {
		if (target[key] !== '' && target[key] !== null) {
			ret[key] = target[key];
		}
	})

	return ret;
}

let formatDateStr = (str, format = 'yyyy年MM月dd日') => {
	let ret = '';

	let date = {
		'y+': str.split(' ')[0].split('-')[0],
		'M+': (str.split(' ')[0].split('-')[1]),
		'd+': str.split(' ')[0].split('-')[2],
		'h+': str.split(' ')[1].split(':')[0],
		'm+': str.split(' ')[1].split(':')[1],
		's+': str.split(' ')[1].split(':')[2]
	}

	date['M+'] = (date['M+']).indexOf('0') == 0 ? parseInt(date['M+'].substring(1)) : parseInt(date['M+']);
	date['d+'] = (date['d+']).indexOf('0') == 0 ? parseInt(date['d+'].substring(1)) : parseInt(date['d+']);

	for (let i in date) {
		if (new RegExp('(' + i + ')').test(format)) {
			format = format.replace(RegExp.$1, date[i])
		}
	}

	return format;
}

let isPtInPoly = (ALon, ALat, APoints) => {
	var iSum = 0,
		iCount;
	var dLon1, dLon2, dLat1, dLat2, dLon;
	if (APoints.length < 3) return false;
	iCount = APoints.length;

	for (var i = 0; i < iCount; i++) {
		if (i == iCount - 1) {
			dLon1 = APoints[i][0];
			dLat1 = APoints[i][1];
			dLon2 = APoints[0][0];
			dLat2 = APoints[0][1];
		} else {
			dLon1 = APoints[i][0];
			dLat1 = APoints[i][1];
			dLon2 = APoints[i + 1][0];
			dLat2 = APoints[i + 1][1];
		}
		//以下语句判断A点是否在边的两端点的水平平行线之间，在则可能有交点，开始判断交点是否在左射线上
		if (((ALat >= dLat1) && (ALat < dLat2)) || ((ALat >= dLat2) && (ALat < dLat1))) {
			if (Math.abs(dLat1 - dLat2) > 0) {
				//得到 A点向左射线与边的交点的x坐标：
				dLon = dLon1 - ((dLon1 - dLon2) * (dLat1 - ALat)) / (dLat1 - dLat2);
				if (dLon < ALon)
					iSum++;
			}
		}
	}

	if (iSum % 2 != 0)
		return true;
	return false;
}

let getUserInfo = () => {
	let userInfo = uni.getStorageSync('userInfo');
	let ret = ''

	if (userInfo) {
		ret = userInfo;
	}

	return ret;
}

let mergeUrls = (url, obj) => {
	let ret = '';
	let arr = [];

	Object.keys(obj).forEach(item => {
		let str = `${item}=${obj[item]}`;

		arr.push(str);
	});

	let params = arr.join('&');

	ret = `${url}?${params}`;

	return ret;
}

let getBaseImages = (tempFilePaths) => {
	return new Promise(async (resolve, reject) => {
		let baseImages = []

		baseImages = tempFilePaths.map(async (tempFilePath) => {
			let path = await pathToBase64(tempFilePath);

			return path;
		})

		let res = await Promise.all(baseImages);

		resolve(res);
	})
}

let toLogin = () => {
	uni.reLaunch({
		url: '/pages/login/login'
	});
}

let getRoutes = () => {
	let pages = getCurrentPages();
	let routes = pages.map((page) => page.route);

	return routes;
}

let getLocation = async (data = {}, type = 'uni') => {
	return await new Promise((resolve, reject) => {		
		if(type == 'Amap'){	
			// const fUN_AmapLocation = uni.requireNativePlugin('FUN-AmapLocation');
			
			// fUN_AmapLocation.permission({}, result => {});
			
			// fUN_AmapLocation.once({}, result => {
			// 	if(result.code === 0){
			// 		resolve(result);
			// 	} else {
			// 		reject();
			// 	}
			// });
		} else {
			let obj = {
				type: 'gcj02',
				isHighAccuracy: true,
				highAccuracyExpireTime: 50000,
				success: (res) => {
					resolve(res);
				},
				fail: (error) => {
					reject();
				}
			};
			
			Object.assign(obj, data);
			
			uni.getLocation(obj);
		}
	})
}

let moveToLocation = async (longitude, latitude, map) => {
	return await new Promise((resolve, reject) => {
		let obj = {
			longitude: longitude,
			latitude: latitude,
			success: () => {
				resolve();
			},
			fail: () => {
				reject();
			}
		}

		map.moveToLocation(obj);
	})
}


let chooseLocation = async (data) => {
	return await new Promise((resolve, reject) => {
		let obj = {
			success: () => {
				resolve();
			},
			fail: () => {
				reject();
			}
		}

		Object.assign(obj, data);

		uni.chooseLocation(obj);
	})
}

let getSystemInfo = async () => {
	return await new Promise((resolve, reject) => {
		uni.getSystemInfo({
			success: (res) => {
				resolve(res);
			}
		});
	});
}

let reverseGeocode = async (longitude, latitude) => {
	return await new Promise((resolve, reject) => {
		let pt = new plus.maps.Point(longitude, latitude);

		plus.maps.Map.reverseGeocode(
			pt, {},
			(event) => {
				let address = event.address; // 转换后的地理位置

				resolve({
					address: address
				});
			},
			(e) => {
				reject(e);
			});
	})
};


let chooseImage = (data = {}, isCompressed = true) => {
	return new Promise((resolve, reject) => {
		let obj = {
			count: 1, //默认9
			sourceType: ['album', 'camera'], //从相册选择
			success: async (res) => {
				// #ifdef APP-VUE || APP-NVUE
				
				if(isCompressed){
					let tempFilePaths = await Promise.all(res['tempFilePaths'].map(async (
						tempFilePath) => {
						return await compressImage({
							src: tempFilePath
						});
					}))
					
					tempFilePaths = tempFilePaths.map(tempFilePath => tempFilePath.tempFilePath);
					
					resolve({
						tempFilePaths
					});
				} else {
					resolve(res);
				}
				
				// #endif
				// #ifdef H5
				resolve(res);
				// #endif
			},
			fail: () => {
				reject();
			}
		}
		
		if(isCompressed) {
			obj.sizeType = ['compressed']
		}
		
		Object.assign(obj, data);

		wx.chooseImage(obj);
	})
}

let chooseImage2 = async() => {
	let res = await permision.requestAndroidPermission('android.permission.WRITE_EXTERNAL_STORAGE');
	return res;
}

let chooseVideo = async (data) => {
	return await new Promise((resolve, reject) => {
		let obj = {
			sizeType: ['compressed'], //可以指定是原图还是压缩图，默认二者都有
			sourceType: ['album', 'camera'], //从相册选择
			success: async (res) => {
				resolve(res);
			},
			fail: () => {
				reject();
			}
		}
	
		Object.assign(obj, data);
	
		uni.chooseVideo(obj);
	})
}

let compressImage = async (data) => {
	return await new Promise((resolve, reject) => {
		let obj = {
			src: '',
			width: '80%',
			height: '80%',
			quality: 80,
			success: res => {
				resolve(res)
			}
		}

		Object.assign(obj, data);

		uni.compressImage(obj)
	})
}

let previewImage = async (data) => {
	return await new Promise((resolve, reject) => {
		let obj = {}

		Object.assign(obj, data);

		uni.previewImage(obj);
	})
}

let getDictLabel = (value, arr, key, key2 = 'dict_label') => {
	let ret = '';
	let item = {};

	if (value !== undefined) {
		item = arr.find(item => item[key] == value);
		ret = item ? item[key2] : ''
	}

	return ret;
}

/**
 * 将时间戳转换为指定格式的时间字符串
 * @param {Long} time  时间戳
 * @param {String} format 格式化，默认'yyyy-MM-dd HH:mm:ss'
 */
let timesFormat = (time, format = 'yyyy-MM-dd HH:mm:ss') => {
	if (!time || time <= 0) {
		return '';
	}
	let date = new Date(time);
	let year = date.getFullYear();
	let month = date.getMonth() + 1; //月份是从0开始 , 所以+1
	let day = date.getDate();
	let hour = date.getHours();
	let min = date.getMinutes();
	let sec = date.getSeconds();
	let preArr = Array.apply(null, Array(10)).map((elem, index) => '0' + index);

	let dateStr = format.replace(/yyyy/g, year)
		.replace(/MM/g, preArr[month] || month)
		.replace(/dd/g, preArr[day] || day)
		.replace(/HH/g, preArr[hour] || hour)
		.replace(/mm/g, preArr[min] || min)
		.replace(/ss/g, preArr[sec] || sec);
	return dateStr;
}

let getMonDayAndSunDay = () => {
	let now = new Date();
	let nowTime = now.getTime() ;
	let day = now.getDay();
	let monDay = '';
	let sunDay = '';
	let oneDayTime = 24*60*60*1000 ;
	
	monDay = nowTime - (day - 1) * oneDayTime;
	
	sunDay = nowTime + (7 - day) * oneDayTime;
	
	return `${timesFormat(monDay, 'yyyy-MM-dd')}~${timesFormat(sunDay, 'yyyy-MM-dd')}`;
}

/**
 * Created by Wandergis on 2015/7/8.
 * 提供了百度坐标（BD09）、国测局坐标（火星坐标，GCJ02）、和WGS84坐标系之间的转换
 */
 
//定义一些常量
const x_PI = 3.14159265358979324 * 3000.0 / 180.0;
const PI = 3.1415926535897932384626;
const a = 6378245.0;
const ee = 0.00669342162296594323;

/**
 * GCJ02 转换为 WGS84
 * @param lng
 * @param lat
 * @returns {*[]}
 */

const transformlat = (lng, lat) => {
    var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
    ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
    ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
    return ret
}
 
const transformlng = (lng, lat) => {
    let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
    ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
    ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
    return ret
}
 
/**
 * 判断是否在国内，不在国内则不做偏移
 * @param lng
 * @param lat
 * @returns {boolean}
 */
const out_of_china = (lng, lat) => {
    return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
}


const gcj02towgs84 = (lng, lat) => {
    if (out_of_china(lng, lat)) {
        return [lng, lat]
    }
    else {
        let dlat = transformlat(lng - 105.0, lat - 35.0);
        let dlng = transformlng(lng - 105.0, lat - 35.0);
        let radlat = lat / 180.0 * PI;
        let magic = Math.sin(radlat);
        magic = 1 - ee * magic * magic;
        let sqrtmagic = Math.sqrt(magic);
        dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
        dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
        let mglat = lat + dlat;
        let mglng = lng + dlng;
        return [lng * 2 - mglng, lat * 2 - mglat]
    }
}

const wgs84togcj02 = (lng, lat) => {
    if (out_of_china(lng, lat)) {
        return [lng, lat]
    }
    else {
        let dlat = transformlat(lng - 105.0, lat - 35.0);
        let dlng = transformlng(lng - 105.0, lat - 35.0);
        let radlat = lat / 180.0 * PI;
        let magic = Math.sin(radlat);
        magic = 1 - ee * magic * magic;
        let sqrtmagic = Math.sqrt(magic);
        dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
        dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
        let mglat = lat + dlat;
        let mglng = lng + dlng;
        return [mglng, mglat]
    }
}

const debounceHandle = (() => {
	let timer = null;
	
	return (fn, wait) => {
		clearTimeout(timer);
		timer = setTimeout(fn, wait)
	}
})();

const randomNum = (...arg) => { 
    switch(arg.length){ 
        case 1: 
            return parseInt(Math.random()* arg[0]+1,10); 
        break; 
        case 2: 
            return parseInt(Math.random()*( arg[1]-arg[0] + 1) + arg[0], 10); 
        break; 
        default: 
			return 0; 
        break; 
    } 
} 

const vibrateLong = async (data = {}) => {
	return await new Promise((resolve, reject) => {
		let obj = {
			success(){
				resolve();
			}
		}
	
		Object.assign(obj, data);
	
		uni.vibrateLong(obj);
	})
}

module.exports = {
	rad,
	getDistance,
	deepClone,
	cleanData,
	formatDateStr,
	isPtInPoly,
	getUserInfo,
	mergeUrls,
	getBaseImages,
	toLogin,
	getRoutes,
	compressImage,
	getLocation,
	moveToLocation,
	getSystemInfo,
	chooseLocation,
	reverseGeocode,
	chooseImage,
	chooseImage2,
	chooseVideo,
	previewImage,
	getDictLabel,
	timesFormat,
	getMonDayAndSunDay,
	wgs84togcj02,
	debounceHandle,
	randomNum,
	vibrateLong
}
